#include <iostream>
#include <string>
#include <regex>


int main ()
{
    //HTTP请求行格式:  GET /shangqiushifan/login?user=lihua&password=123456 HTTP/1.1\r\n
    // std::string src = "GET /shangqiushifan/login?user=lihua&password=123456 HTTP/1.1";
    std::string src = "GET /shangqiushifan/login?user=lihua&password=123456 HTTP/1.1\r\n";
    std::smatch matches;
    //1.请求行中方法的匹配 GET POST PUT DELETE HEAD...
    //(GET|POST|PUT|DELETE|HEAD) 表示匹配并提取其中任意一个字符串
    // std::regex e("(GET|POST|PUT|DELETE|HEAD) .*");

    //2.请求行中路径(资源路径)的匹配
    //[^?]*  [^?]表示匹配非问号字符,后边的*表示提取0次或多次
    // std::regex e("(GET|POST|PUT|DELETE|HEAD) ([^?]*).*");

    //3.请求行中查询字符串的提取
    //\\?(.*)   \\?表示原始的 ? 字符,(.*)表示提取?之后的任意字符0次或多次,直到遇到空格
    // std::regex e("(GET|POST|PUT|DELETE|HEAD) ([^?]*)\\?(.*) .*");

    //4.请求行中HTTP协议版本的提取
    //因为浏览器中使用 HTTP/1.0 HTTP/1.1最多
    //(HTTP/1\\.[01]):   \\.是因为.在正则表达式中有特殊含义,除了\r\n都能匹配,\\.表示原始.字符,[01]表示 0 or 1
    //                   整体表示匹配 HTTP/1.0 or HTTP/1.1
    // std::regex e("(GET|POST|PUT|DELETE|HEAD) ([^?]*)\\?(.*) (HTTP/1\\.[01])");

    //5.细节处理
    //结尾带 \r \r\n
    // std::regex e("(GET|POST|PUT|DELETE|HEAD) ([^?]*)\\?(.*) (HTTP/1\\.[01])(?:\n|\r\n)");
    //请求资源路径后边没有参数
    std::regex e("(GET|POST|PUT|DELETE|HEAD) ([^?]*)(?:\\?(.*))? (HTTP/1\\.[01])(?:\n|\r\n)");


    bool ret = std::regex_match(src,matches,e);
    if(ret == false){
        //匹配失败就更不用说提取了
        return -1;
    }
    //匹配成功,循环遍历
    for(const auto& s : matches){
        std::cout << s << std::endl;
    }
    return 0;
}